#![cfg(target_os = "windows")]
#![cfg(feature = "dx11")]
use windows::{core::ComInterface, Graphics::DirectX::{Direct3D11::IDirect3DSurface, DirectXPixelFormat}, Win32::{Graphics::Direct3D11::{ID3D11Device, ID3D11Texture2D}, System::WinRT::Direct3D11::IDirect3DDxgiInterfaceAccess}};
use std::error::Error;
use std::fmt::Display;
use crate::prelude::{CaptureStream, VideoFrame};
#[derive(Debug, Clone)]
pub enum WindowsDx11VideoFrameError {
Other(String),
}
impl Display for WindowsDx11VideoFrameError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Other(error) => f.write_fmt(format_args!("WindowsDx11VideoFrameError::Other(\"{}\")", error)),
}
}
}
impl Error for WindowsDx11VideoFrameError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
fn description(&self) -> &str {
"description() is deprecated; use Display"
}
fn cause(&self) -> Option<&dyn Error> {
self.source()
}
}
pub trait WindowsDx11VideoFrame {
fn get_dx11_surface(&self) -> Result<(IDirect3DSurface, DirectXPixelFormat), WindowsDx11VideoFrameError>;
fn get_dx11_texture(&self) -> Result<(ID3D11Texture2D, DirectXPixelFormat), WindowsDx11VideoFrameError>;
}
impl WindowsDx11VideoFrame for VideoFrame {
fn get_dx11_surface(&self) -> Result<(IDirect3DSurface, DirectXPixelFormat), WindowsDx11VideoFrameError> {
self.impl_video_frame.frame.Surface()
.map_err(|e| WindowsDx11VideoFrameError::Other(format!("Failed to get frame surface: {}", e.to_string())))
.map(|surface| (surface, self.impl_video_frame.pixel_format))
}
fn get_dx11_texture(&self) -> Result<(ID3D11Texture2D, DirectXPixelFormat), WindowsDx11VideoFrameError> {
let (surface, pixel_format) = self.get_dx11_surface()?;
let dxgi_interface_access = surface.cast::<IDirect3DDxgiInterfaceAccess>()
.map_err(|e| WindowsDx11VideoFrameError::Other(format!("Failed to cast surface to dxgi interface access: {}", e.to_string())))?;
let texture = unsafe { dxgi_interface_access.GetInterface::<ID3D11Texture2D>() }
.map_err(|e| WindowsDx11VideoFrameError::Other(format!("Failed to get ID3D11Texture interface {}", e.to_string())))?;
Ok((texture, pixel_format))
}
}
pub trait WindowsDx11CaptureStream {
fn get_dx11_device(&self) -> ID3D11Device;
}
impl WindowsDx11CaptureStream for CaptureStream {
fn get_dx11_device(&self) -> ID3D11Device {
self.impl_capture_stream.d3d11_device.clone()
}
}